home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 44 / Amiga Format CD44 (1999-08-26)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-10].iso / -serious- / misc / telewords / original / telewords.c < prev   
C/C++ Source or Header  |  1999-07-12  |  3KB  |  142 lines

  1. /*
  2.    Telewords takes a telephone number as the single input argument
  3.    and outputs, one per line, all of the equivalent character strings,
  4.    in the hope that one of them will be a real word, or at least
  5.    pronouncable..  The digits 0 and 1, * which don't have letters,
  6.    are printed as themselves.  Command line options allow you to change
  7.    the string of characters into which each digit is mapped.
  8.    This is helpful for selecting a PIN number on automatic teller machines
  9.    that put q and z on the 1 (Why doesn't the phone company do that?).
  10.    The phone number can have a arbitrary number of digits, and non-digits
  11.    are ignored: '(301) 555-1212' is the same as '3015551212', provided the
  12.    space is properly quoted to the shell.
  13.   
  14.    Written by James W. Williams
  15.    williams@cs.umd.edu
  16.    Last hacked on 28 January 1990.
  17.       This really ought to be ASNIfied at some point...
  18. */
  19.  
  20. #include <stdio.h>
  21. #include <ctype.h>
  22.  
  23. #define USAGE    fprintf(stderr, "\tusage: telewords [-<digit>c...] ...  telephone-number\n")
  24.  
  25. char    *table[]   = {    "0",    /* mapping table for input digits. */
  26.             "1",    /* The -<digit> options can modify */
  27.             "abc",    /* this table. */
  28.             "def",
  29.             "ghi",
  30.             "jkl",
  31.             "mno",
  32.             "prs",
  33.             "tuv",
  34.             "wxy"
  35.             },
  36.     teleword[128];      /* buffer to hold output word. */
  37.  
  38.  
  39. /*
  40.  * A recursive subroutine to do the dirty work.
  41.  */
  42.  
  43. void
  44. doLetter(numberString, currentLetter)
  45. char    *numberString,        /* pointer into input phone number string */
  46.     *currentLetter;    /* pointer into the output word string */
  47. {
  48.  
  49.     register char    ch, *mapstring;
  50.  
  51.     /* get the string of characters to use for the leading digit
  52.        in numberString and iterate over each character.  currentLetter
  53.        points to the position in teleword into which to stick each
  54.        possible mapping of the current digit.
  55.      */
  56.     mapstring = table[*numberString-'0'];
  57.     while (ch = *mapstring++) {
  58.         *currentLetter = ch;
  59.         if (*(numberString+1) == '\0') {
  60.             printf("%s\n", teleword);
  61.         }
  62.         else {
  63.             doLetter(numberString+1, currentLetter+1);
  64.         }
  65.     }
  66. }
  67.  
  68. int
  69. main(argc, argv)
  70. int argc;
  71. char **argv;
  72. {
  73.     int i;
  74.     char *argptr, *cp = teleword, *to, *from;
  75.  
  76.         if (argc < 2) {
  77.         USAGE;
  78.         exit(1);
  79.         }
  80.  
  81.     /* process arguments */
  82.     argv++; argc--;
  83.     while (**argv == '-') {
  84.         argptr = *argv;
  85.         switch (argptr[1]) {
  86.         case '0':
  87.         case '1':
  88.         case '2':
  89.         case '3':
  90.         case '4':
  91.         case '5':
  92.         case '6':
  93.         case '7':
  94.         case '8':
  95.         case '9':
  96.             if (argptr[2] == '\0') {
  97.                 /* null string means map this digit 
  98.                  * into itself.
  99.                  */
  100.                 table[argptr[1]-'0'][0] = argptr[1];
  101.                 table[argptr[1]-'0'][1] = '\0';
  102.             }
  103.             else {
  104.                 /* the map for this digit is the string
  105.                  * following the -<digit>
  106.                  */
  107.                 table[argptr[1]-'0'] = &argptr[2];
  108.             }
  109.             break;
  110.         default: /* unknown option */
  111.             fprintf(stderr, "Unknown option letter %c.\n", argptr[1]);
  112.         }
  113.         argv++; argc--;
  114.     }
  115.  
  116.     if (argc > 1) {
  117.         fprintf(stderr, "Too many arguments!\n");
  118.         USAGE;
  119.         exit (1);
  120.     }
  121.     else if (argc < 1) {
  122.         fprintf(stderr, "Missing telephone number.\n");
  123.         USAGE;
  124.         exit (1);
  125.     }
  126.  
  127.     /* squeeze out all non-digits from argv[0].  This simplifies doLetter.
  128.      */
  129.     to = from = argv[0];
  130.     while (*from != '\0') {
  131.         if (isdigit(*from)) {
  132.             *to++ = *from++;
  133.         }
  134.         else {
  135.             from++;
  136.         }
  137.     }
  138.     *to = '\0';
  139.  
  140.     doLetter(argv[0], teleword);
  141. }
  142.